﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Windows.Ink;
using System.Runtime.Serialization;
using xml_classes;
using Ionic.Zip;

using Polygon = System.Windows.Shapes.Polygon;

namespace editor
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 
    public partial class MainWindow : Window
    {
        private ScreenFromEditor _screen = new ScreenFromEditor();
        bool drawing_polygon = false;

        Polygon ghost;
        InkCanvas inkCanvas1 = new InkCanvas();
        private ImageFitToScreen _GameScreen = new ImageFitToScreen("Background", "", 0, 0);
        private ImageFitToScreen _WalkingMap = new ImageFitToScreen("WalkingMap", "", 0, 0);
        Point StartPoint = new Point(-1, -1);
        Dictionary<Color, short> ColorsDepths = new Dictionary<Color,short>();
        String[] args = App.mArgs;
        DrawingAttributes inkAttributes = new DrawingAttributes();

        Image Charecter = new Image
        {
            Source = new BitmapImage(new Uri(@"C:\Users\Karmel\Documents\Visual Studio 2010\Projects\AdventureGame\AdventureGameEditor\Images/Charecter.png", UriKind.Absolute)),
            Height = 321 / 1.5,
            Width = 250 / 1.5,
        };

        public MainWindow()
        {
            InitializeComponent();
            inkAttributes.IsHighlighter = true;
            inkCanvasWalk.DefaultDrawingAttributes = inkAttributes;
            inkCanvasPolygons.DefaultDrawingAttributes = inkAttributes;
            inkCanvasFront.DefaultDrawingAttributes = inkAttributes;
            comboBoxPolygonType.ItemsSource = Enum.GetValues(typeof(TypeOfPolygon));
            
            if (args != null)
            {
               
            }
        }

        private void ChangeColor(object sender, RoutedEventArgs e)
        {
            SolidColorBrush solidBrush = ((Button)sender).Background as SolidColorBrush;
            StrokeCollection SC = inkCanvas1.GetSelectedStrokes();
            if (IsEditingWalk())
            {
                if (!ColorsDepths.ContainsKey(solidBrush.Color))
                {
                    ColorsDepths[solidBrush.Color] = (short)sliderColorDepth.Value;
                }

                sliderColorDepth.Foreground = ((Button)sender).Background;
                sliderColorDepth.Background = ((Button)sender).Background;
                sliderColorDepth.BorderBrush = ((Button)sender).Background;

                RefreshWalkingDetails();
            }

            if (SC.Count == 0)
            {
                inkAttributes.Color = solidBrush.Color;
            }
            else
            {
                for (int i = 0; i < SC.Count; i++)
                {
                    SC.ElementAt(i).DrawingAttributes.Color = solidBrush.Color;
                }
            }
        }

        void eraseByPointEditingMode_Click(object sender, RoutedEventArgs e)
        {
            inkCanvasWalk.EditingMode = InkCanvasEditingMode.EraseByPoint;
        }

        void selectEditingMode_Click(object sender, RoutedEventArgs e)
        {
            inkCanvasWalk.EditingMode = InkCanvasEditingMode.Select;
            inkCanvasPolygons.EditingMode = InkCanvasEditingMode.Select;
            inkCanvasFront.EditingMode = InkCanvasEditingMode.None;
        }

        void inkEditingMode_Click(object sender, RoutedEventArgs e)
        {
            inkCanvasWalk.EditingMode = InkCanvasEditingMode.Ink;
        }

        void radioButton0_Checked(object sender, RoutedEventArgs e)
        {
            inkCanvasPolygons.EditingMode = InkCanvasEditingMode.None;
            inkCanvasFront.EditingMode = InkCanvasEditingMode.None;
        }

        void SetBackground(string path)
        {
            ImageBrush berriesBrush = new ImageBrush();
            berriesBrush.ImageSource =
                new BitmapImage(
                    new Uri(path, UriKind.Relative)
                );
            _GameScreen = new ImageFitToScreen("Background", path, berriesBrush.ImageSource.Width, berriesBrush.ImageSource.Height);
            inkCanvasBackground.Background = berriesBrush;

        }

        private void LoadBackgroundImage(object sender, RoutedEventArgs e)
        {
            // Create OpenFileDialog 
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();



            // Set filter for file extension and default file extension 
            dlg.DefaultExt = ".jpg";
            dlg.Filter = "JPG Files (*.jpg)|*.jpg";


            // Display OpenFileDialog by calling ShowDialog method 
            Nullable<bool> result = dlg.ShowDialog();


            // Get the selected file name and display in a TextBox 
            if (result == true)
            {
                // Open document 
                string filename = dlg.FileName;
                SetBackground(filename);
                button_removeBackground.IsEnabled = true;
            }
        }

        private void writeEditorFilesToFiles(string WalkingPath, string PolygonPath)
        {
            using (FileStream fs = new FileStream(WalkingPath, FileMode.Create))
            {
                inkCanvasWalk.Strokes.Save(fs);
                fs.Close();
            }
            using (FileStream fs = new FileStream(PolygonPath, FileMode.Create))
            {
                inkCanvasPolygons.Strokes.Save(fs);
                fs.Close();
            }
        }

        private List<EntryMemoryStream> writeEditorFilesToMemory()
        {
            EntryMemoryStream memoWalk = new EntryMemoryStream("Walking.isf");
            EntryMemoryStream memoPolygon = new EntryMemoryStream("Polygons.isf");
            List<EntryMemoryStream> memoList = new List<EntryMemoryStream>();

            inkCanvasWalk.Strokes.Save(memoWalk);
            memoWalk.Seek(0, SeekOrigin.Begin);
            inkCanvasPolygons.Strokes.Save(memoPolygon);
            memoPolygon.Seek(0, SeekOrigin.Begin);


            memoList.Add(memoWalk);
            memoList.Add(memoPolygon);

            return memoList;

        }

        private void LoadAndRunOverWork(object sender, RoutedEventArgs e)
        {
            // Create OpenFileDialog 
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();

            // Set filter for file extension and default file extension 
            dlg.DefaultExt = ".AGS";
            dlg.Filter = "AGS Files (*.AGS)|*.AGS";


            // Display OpenFileDialog by calling ShowDialog method 
            Nullable<bool> result = dlg.ShowDialog();


            // Get the selected file name and display in a TextBox 
            if (result == true)
            {
                LoadSavedFile(dlg.FileName, false);
            }
        }

        private void LoadSavedFile(string Path, bool Appened)
        {
            ZipFile savedFile = new ZipFile(Path);

            StrokeCollection strokes;

            MemoryStream memoData = ExtractStreamFromZip(Path, "Data.Xml");
            if (memoData != null)
            {
                _screen = (ScreenFromEditor)XMLmanager.DeserializeFromMemory(_screen.GetType(), memoData);
                if (File.Exists(_screen._GameScreen.GetPath()))
                {
                    SetBackground(_screen._GameScreen.GetPath());
                }
                memoData.Close();
            }

            MemoryStream memoWalk = ExtractStreamFromZip(Path, "Walking.isf");
            if (memoWalk != null)
            {
                strokes = new StrokeCollection(memoWalk);
                memoWalk.Close();
                if (Appened)
                {
                    foreach (Stroke stroke in strokes)
                    {
                        inkCanvasPolygons.Strokes.Add(stroke);
                    }
                }
                else
                {
                    inkCanvasWalk.Strokes = strokes;
                }
            }

            MemoryStream memoPolygons = ExtractStreamFromZip(Path, "Polygons.isf");
            if (memoPolygons != null)
            {
                strokes = new StrokeCollection(memoPolygons);
                memoPolygons.Close();
                int StrokeCount = strokes.Count;
                for (int i = 0; i < StrokeCount; i++)
                {
                    PolygonStroke PS = new PolygonStroke(strokes.First());
                    PS.setName(_screen._polygons.First().getName());
                    PS.SetPositionOfwhereToLookFromAtThePolygon(_screen._polygons.First().GetPositionOfwhereToLookFromAtThePolygon().X, _screen._polygons.First().GetPositionOfwhereToLookFromAtThePolygon().Y);
                    PS.SetType(_screen._polygons.First().GetType());
                    strokes.RemoveAt(0);
                    _screen._polygons.RemoveAt(0);
                    strokes.Add(PS);
                }
                if (Appened)
                {
                    foreach (Stroke stroke in strokes)
                    {
                        inkCanvasPolygons.Strokes.Add(stroke);
                    }
                }
                else
                {
                    inkCanvasPolygons.Strokes = strokes;
                } 
            }
        }

        private void CopyPolygonsFromInkCanvas(List<xml_classes.Polygon> polygons)
        {
            foreach (PolygonStroke Pstroke in inkCanvasPolygons.Strokes)
            {
                xml_classes.Polygon Pol = new xml_classes.Polygon(Pstroke);
                polygons.Add(Pol);
            }
        }

        private void LoadAndAddWork(object sender, RoutedEventArgs e)
        {
            // Create OpenFileDialog 
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();

            // Set filter for file extension and default file extension 
            dlg.DefaultExt = ".isf";
            dlg.Filter = "ISF Files (*.isf)|*.isf";


            // Display OpenFileDialog by calling ShowDialog method 
            Nullable<bool> result = dlg.ShowDialog();


            // Get the selected file name and display in a TextBox 
            if (result == true)
            {
                LoadSavedFile(dlg.FileName, true);
            }
        }

        private void AllDone()
        {
            DirectoryInfo DI = new DirectoryInfo(Directory.GetCurrentDirectory());
            string ScreenDir = DI.FullName + @"\GameScreens\";

            FileInfo ZipFile = new FileInfo(ScreenDir + textBox1.Text + ".AGS");
 
            List<EntryMemoryStream> memoList = new List<EntryMemoryStream>();

            memoList.Add(SaveAsBMPToMemory());
            memoList.Add(writeDataToMemoryXML());
            memoList.AddRange(writeEditorFilesToMemory());
            if (File.Exists(_GameScreen.GetPath()))
            {
                EntryMemoryStream BGmemo = new EntryMemoryStream("ScreenBackgroud.Jpg");
                FileStream BGFile = File.OpenRead(_GameScreen.GetPath());
                BGFile.CopyTo(BGmemo);
                BGmemo.Seek(0, SeekOrigin.Begin);
                memoList.Add(BGmemo);
            }

            AddStreamsToZip(ZipFile.FullName, memoList);
            foreach (EntryMemoryStream item in memoList)
            {
                item.Close();
            }


            string sMessageBoxText = ":קובץ הפלט שלך ממוקם ב" + "\n" + ScreenDir;
            string sCaption = "Screen \"" + textBox1.Text + "\" is ready";

            MessageBoxButton btnMessageBox = MessageBoxButton.OK;
            MessageBoxImage icnMessageBox = MessageBoxImage.Information;
            MessageBoxResult rsltMessageBox = MessageBox.Show(sMessageBoxText, sCaption, btnMessageBox, icnMessageBox, MessageBoxResult.None, MessageBoxOptions.RightAlign);


        }

        private void SaveAsBMPToFile(string path)
        {
            RenderTargetBitmap rtb = new RenderTargetBitmap((int)this.inkCanvasWalk.Width, (int)this.inkCanvasWalk.Height, 0, 0, PixelFormats.Pbgra32);

            StrokeCollection TempStrokeCollection = inkCanvasWalk.Strokes.Clone();

            for (int i = 0; i < inkCanvasWalk.Strokes.Count; i++)
            {
                //inkCanvasWalk.Strokes.ElementAt(i).DrawingAttributes.Color = Colors.White;
                inkCanvasWalk.Strokes.ElementAt(i).DrawingAttributes.IsHighlighter = false;
            }
            rtb.Render(this.inkCanvasWalk);

            inkCanvasWalk.Strokes = TempStrokeCollection;

            BmpBitmapEncoder encoder = new BmpBitmapEncoder();

            BitmapFrame BMF = BitmapFrame.Create(rtb);

            int stride = ((BMF.PixelWidth * BMF.Format.BitsPerPixel) + 7) / 8;
            _screen._Stride = stride;
            _screen._Width = BMF.PixelWidth;
            _screen._Height = BMF.PixelHeight;
            // Create data array to hold source pixel data
            byte[] data = new byte[stride * BMF.PixelHeight];

            // Copy source image pixels to the data array
            BMF.CopyPixels(data, stride, 0);

            FloodFill(ref data, (int)StartPoint.X, (int)StartPoint.Y, ref stride, sliderCharecterSize.Value, BMF.PixelWidth, BMF.PixelHeight);

            BitmapSource BMS = BitmapSource.Create((int)BMF.Width, (int)BMF.Height, BMF.DpiX, BMF.DpiY, BMF.Format, BMF.Palette, data, stride);

            BMF = BitmapFrame.Create(BMS);

            encoder.Frames.Add(BMF);

            FileStream file = new FileStream(path, FileMode.Create);

            encoder.Save(file);
            file.Close();

            _WalkingMap = new ImageFitToScreen("WalkingMap", path, inkCanvasWalk.Width, inkCanvasWalk.Height);
            inkCanvasWalk.UpdateLayout();


        }

        private EntryMemoryStream SaveAsBMPToMemory()
        {
            RenderTargetBitmap rtb = new RenderTargetBitmap((int)this.inkCanvasWalk.Width, (int)this.inkCanvasWalk.Height, 0, 0, PixelFormats.Pbgra32);

            StrokeCollection TempStrokeCollection = inkCanvasWalk.Strokes.Clone();

            for (int i = 0; i < inkCanvasWalk.Strokes.Count; i++)
            {
                //inkCanvasWalk.Strokes.ElementAt(i).DrawingAttributes.Color = Colors.White;
                inkCanvasWalk.Strokes.ElementAt(i).DrawingAttributes.IsHighlighter = false;
            }
            rtb.Render(this.inkCanvasWalk);

            inkCanvasWalk.Strokes = TempStrokeCollection;

            BmpBitmapEncoder encoder = new BmpBitmapEncoder();

            BitmapFrame BMF = BitmapFrame.Create(rtb);

            int stride = ((BMF.PixelWidth * BMF.Format.BitsPerPixel) + 7) / 8;
            _screen._Stride = stride;
            _screen._Width = BMF.PixelWidth;
            _screen._Height = BMF.PixelHeight;
            // Create data array to hold source pixel data
            byte[] data = new byte[stride * BMF.PixelHeight];

            // Copy source image pixels to the data array
            BMF.CopyPixels(data, stride, 0);

            FloodFill(ref data, (int)StartPoint.X, (int)StartPoint.Y, ref stride, sliderCharecterSize.Value, BMF.PixelWidth, BMF.PixelHeight);

            BitmapSource BMS = BitmapSource.Create((int)BMF.Width, (int)BMF.Height, BMF.DpiX, BMF.DpiY, BMF.Format, BMF.Palette, data, stride);

            BMF = BitmapFrame.Create(BMS);

            encoder.Frames.Add(BMF);

            EntryMemoryStream memo = new EntryMemoryStream("Walking.Bmp");

            encoder.Save(memo);
            memo.Seek(0, SeekOrigin.Begin);
            

            _WalkingMap = new ImageFitToScreen("WalkingMap", "", inkCanvasWalk.Width, inkCanvasWalk.Height);
            inkCanvasWalk.UpdateLayout();


            return memo;
            

        }

        private void SetPixleWithGrey(ref byte[] data, int x, int y, ref int stride, byte GreyValue)
        {
            GreyValue *= 2;
            GreyValue += 23;
            int xIndex = x * 4;
            int yIndex = y * stride;
            data[xIndex + yIndex] = GreyValue;
            data[xIndex + yIndex + 1] = GreyValue;
            data[xIndex + yIndex + 2] = GreyValue;
        }

        private void SetPixleWithColor(ref byte[] data, int x, int y, ref int stride, Color c)
        {
            int xIndex = x * 4;
            int yIndex = y * stride;
            data[xIndex + yIndex] = c.B;
            data[xIndex + yIndex + 1] = c.G;
            data[xIndex + yIndex + 2] = c.R;
        }

        private Color GetColorFromBitmap(ref byte[] data, int x, int y, ref int stride)
        {
            int xIndex = x * 4;
            int yIndex = y * stride;
            Color c = Colors.Red;
            c.B = data[xIndex + yIndex];
            c.G = data[xIndex + yIndex + 1];
            c.R = data[xIndex + yIndex + 2];
            c.A = 255;

            return c;
        }


        private void FloodFill(ref byte[] data, int StartX, int StartY, ref int stride, double StartValue, int width, int height)
        {
            double diff = 0;
            
            List<Node> listNotBLacks = new List<Node>();
            List<Node> listToGreyScale = new List<Node>();

            for (int i = 0; i < 6; i++)
            {
                listNotBLacks.Clear();
                GetNotBlackWraperList(ref data, ref stride, width, height, listNotBLacks);

                while (listNotBLacks.Count > 0)
                {
                    Node node;

                    node = listNotBLacks.First();
                    listNotBLacks.RemoveAt(0);
                    int x = node.GetX();
                    int y = node.GetY();
                    SetPixleWithColor(ref data, x, y, ref stride, Colors.LightPink);
                }
            }

            listToGreyScale.Add(new Node(StartX, StartY, StartValue));
            while (listToGreyScale.Count > 0)
            {
                Node node;

                node = listToGreyScale.First();
                listToGreyScale.RemoveAt(0);

                int x = node.GetX();
                int y = node.GetY();
                if (x >= width || x < 0 || y >= height || y < 0)
                {
                    continue;
                }
                Color c = GetColorFromBitmap(ref data, x, y, ref stride);
                if (IsGreyColor(ref c))
                {
                    continue;
                }
                if (c == Colors.Black || c == Colors.LightPink)
                {
                    continue;
                }

                if (ColorsDepths.ContainsKey(c))
                {
                    diff = ((double)ColorsDepths[c] / (double)height);
                }

                double CurrentValue = node.GetColor();
                SetPixleWithGrey(ref data, x, y, ref stride, (byte)(CurrentValue));
                
                listToGreyScale.Add(new Node(x + 1, y, CurrentValue));
                listToGreyScale.Add(new Node(x - 1, y, CurrentValue));
                listToGreyScale.Add(new Node(x, y + 1, CurrentValue + diff));
                listToGreyScale.Add(new Node(x, y - 1, CurrentValue - diff));
            }
        }

        private void GetNotBlackWraperList(ref byte[] data, ref int stride, int width, int height, List<Node> listNotBLacks)
        {
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    Color c = GetColorFromBitmap(ref data, i, j, ref stride);
                    if (c != Colors.Black && c != Colors.LightPink)
                    {
                        if (CheckNebForBlacks(ref data, ref stride, width, height, listNotBLacks, ref i, ref j))
                        {
                            listNotBLacks.Add(new Node(i, j, 0));
                        }
                    }
                }
            }
        }

        private bool CheckNebForBlacks(ref byte[] data, ref int stride, int width, int height, List<Node> listNotBLacks, ref int i, ref int j)
        {
            for (int p = -1; p <= 1; p++)
            {
                if (i + p >= width || i + p < 0)
                {
                    continue;
                }
                for (int q = -1; q <= 1; q++)
                {
                    if (j + q >= height || j + q < 0)
                    {
                        continue;
                    }
                    Color c2 = GetColorFromBitmap(ref data, i+p, j+q, ref stride);
                    if (c2 == Colors.Black || c2 == Colors.LightPink || i == width-1 || i == 0 || j == height-1 || j == 0)
                    {
                        return true;
                    }

                }
            }
            return false;
        }
        private static bool IsGreyColor(ref Color c)
        {
            return (c.B == c.G && c.G == c.R && c.R >= 23 && c.R <= 223);
        }


        private void RemoveBackgroundImage(object sender, RoutedEventArgs e)
        {
            _GameScreen = new ImageFitToScreen("Background", "", 0, 0);
            inkCanvasBackground.Background = null;
            button_removeBackground.IsEnabled = false;
        }

        private void SetThickness(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            inkAttributes.Width = ((Slider)sender).Value;
            inkAttributes.Height = ((Slider)sender).Value;
            inkCanvasWalk.EraserShape = inkCanvasPolygons.EraserShape = new RectangleStylusShape(((Slider)sender).Value, ((Slider)sender).Value);
        }

        private void EraseAll(object sender, RoutedEventArgs e)
        {
            MessageBoxButton btnMessageBox = MessageBoxButton.OKCancel;
            MessageBoxImage icnMessageBox = MessageBoxImage.Information;
            MessageBoxResult rsltMessageBox = MessageBox.Show("אתה עומד למחוק הכל מכל השכבות" + "\n" + "?האם ברצונך להמשיך", "מחק מכל השכבות", btnMessageBox, icnMessageBox, MessageBoxResult.None, MessageBoxOptions.RightAlign);
            if (rsltMessageBox == MessageBoxResult.Cancel)
            {
                return;
            }
            inkCanvasWalk.Strokes.Clear();
            inkCanvasPolygons.Strokes.Clear();
            inkCanvasFront.Strokes.Clear();
            inkCanvasFront.Children.Clear();
            StartPoint.X = -1;
            StartPoint.Y = -1;

        }

        private void SelectionChanged(object sender, EventArgs e)
        {
            StrokeCollection SC = ((InkCanvas)sender).GetSelectedStrokes();
            if (SC.Count == 0)
            {
                button17.IsEnabled = false;
            }
            else
            {
                button17.IsEnabled = true;
            }

            if (IsEditingPolygons())
            {
                RefreshPolygonDetails(SC);
            }
        }

        private void RefreshPolygonDetails(StrokeCollection SC)
        {
            if (SC.Count == 1)
            {
                groupBoxPolygon.Visibility = Visibility.Visible;
                PolygonStroke Pstroke = (PolygonStroke)SC.First();

                textBoxPolygonName.Text = Pstroke.getName();

                textBoxPolygonLookFrom.Text = "(" + Pstroke.GetPositionOfwhereToLookFromAtThePolygon().X.ToString() + "," + Pstroke.GetPositionOfwhereToLookFromAtThePolygon().Y.ToString() + ")";


                comboBoxPolygonType.SelectedItem = Pstroke.GetType();



            }
            else
            {
                groupBoxPolygon.Visibility = Visibility.Hidden;
                textBoxPolygonName.Text = "";
                textBoxPolygonLookFrom.Text = "";
                comboBoxPolygonType.SelectedItem = null;
            }
        }

        private void EraseSelection(object sender, RoutedEventArgs e)
        {
            StrokeCollection SC = inkCanvas1.GetSelectedStrokes();
            if (SC.Count != 0)
            {
                for (int i = 0; i < SC.Count; i++)
                {
                    inkCanvas1.Strokes.Remove(SC.ElementAt(i));
                }
                button17.IsEnabled = false;
            }
        }

        private void MouseMove(object sender, MouseEventArgs e)
        {
            if (!drawing_polygon)
            {
                return;
            }
            if (ghost.Points.Count > 0)
            {
                ghost.Points.RemoveAt(ghost.Points.Count - 1);
                ghost.Points.Add(Mouse.GetPosition((InkCanvas)sender));
            }
        }

        private void MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (drawing_polygon)
            {
                ghost.Points.RemoveAt(ghost.Points.Count - 1);

                ghost.Stroke = Brushes.Yellow;

                ((InkCanvas)sender).Children.Remove(ghost);

                StylusPointCollection SPC = new StylusPointCollection();
                for (int i = 0; i < ghost.Points.Count; i++)
                {
                    SPC.Add(new StylusPoint(ghost.Points.ElementAt(i).X, ghost.Points.ElementAt(i).Y));
                }
                SPC.Add(new StylusPoint(ghost.Points.ElementAt(0).X, ghost.Points.ElementAt(0).Y));
                Stroke stroke1 = new Stroke(SPC);

                stroke1.DrawingAttributes.IsHighlighter = true;
                stroke1.DrawingAttributes.Color = inkAttributes.Color;
                stroke1.DrawingAttributes.Width = 5;
                stroke1.DrawingAttributes.Height = 5;


                ((InkCanvas)sender).Strokes.Add(new PolygonStroke(stroke1));
                drawing_polygon = false;
                ghost = null;

            }
        }

        private void radioButton0_Unchecked(object sender, RoutedEventArgs e)
        {
            if (drawing_polygon == true)
            {
                inkCanvas1.Children.Remove(ghost);
                ghost = null;
                drawing_polygon = false;
            }
        }

        private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (ghost == null)
            {
                drawing_polygon = true;
                ghost = new Polygon();
                ghost.Stroke = Brushes.Aqua;
                ghost.StrokeThickness = 2;
                ((InkCanvas)sender).Children.Add(ghost);
            }
            if (((InkCanvas)sender).EditingMode == InkCanvasEditingMode.None)
            {
                if (!drawing_polygon)
                {
                    return;
                }
                ghost.Points.Add(Mouse.GetPosition(((InkCanvas)sender)));
                if (ghost.Points.Count == 1)
                    ghost.Points.Add(Mouse.GetPosition(((InkCanvas)sender)));
            }
        }

        private void writeDataToXMLToFile(string path)
        {
            _screen._GameScreen = _GameScreen;
            _screen._WalkingMap = _WalkingMap;
            List<xml_classes.Polygon> polygons = new List<xml_classes.Polygon>();
            CopyPolygonsFromInkCanvas(polygons);
            _screen._polygons = polygons;
            _screen._StartingPoint = new Microsoft.Xna.Framework.Vector2((float)StartPoint.X, (float)StartPoint.Y);

            XMLmanager.Serialize(_screen, path);
        }

        private EntryMemoryStream writeDataToMemoryXML()
        {
            _screen._GameScreen = _GameScreen;
            _screen._WalkingMap = _WalkingMap;
            List<xml_classes.Polygon> polygons = new List<xml_classes.Polygon>();
            CopyPolygonsFromInkCanvas(polygons);
            _screen._polygons = polygons;
            _screen._StartingPoint = new Microsoft.Xna.Framework.Vector2((float)StartPoint.X, (float)StartPoint.Y);

            return XMLmanager.SerializeToMemory(_screen,"Data.Xml");
        }

        private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (((TextBox)sender).Text.Equals(""))
            {
                button2.IsEnabled = false;
            }
            else
            {
                button2.IsEnabled = true;
            }
        }

        private void SizeChanged(object sender, SizeChangedEventArgs e)
        {
            double pHeight = e.NewSize.Height / e.PreviousSize.Height;
            double pWidth = e.NewSize.Width / e.PreviousSize.Width;

            foreach (Stroke stroke in ((InkCanvas)sender).Strokes)
            {
                int count = stroke.StylusPoints.Count;
                for (int i = 0; i < count; i++)
                {
                    StylusPoint sp = stroke.StylusPoints.ElementAt(0);
                    sp.X *= pWidth;
                    sp.Y *= pHeight;
                    stroke.StylusPoints.Add(sp);
                    stroke.StylusPoints.RemoveAt(0);
                }
                if (!((InkCanvas)sender).Equals(inkCanvasPolygons))
                {
                    stroke.DrawingAttributes.Width *= pWidth;
                    stroke.DrawingAttributes.Height *= pHeight;
                }
            }
            if (sender.Equals(inkCanvasFront))
            {
                if (!(StartPoint.X == -1 && StartPoint.Y == -1))
                {
                    StartPoint.X *= pWidth;
                    StartPoint.Y *= pHeight;
                    Charecter.Height *= pHeight;
                    Charecter.Width *= pWidth;
                    RefreshScreenDetails();
                }
            }
            
        }

        private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

            char[] delimiters = new char[] { ' ', 'X', 'x' };

            if (e.AddedItems.Count > 0)
            {
                string[] dimensions_new = ((ComboBoxItem)(e.AddedItems[0])).Content.ToString().Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                if (e.RemovedItems.Count > 0)
                {
                    string[] dimensions_old = ((ComboBoxItem)(e.RemovedItems[0])).Content.ToString().Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                    if (dimensions_old.Count() > 1)
                    {
                        slider1.Value *= Double.Parse(dimensions_new[0]) / Double.Parse(dimensions_old[0]);
                    }
                }
                if (dimensions_new.Count() > 1)
                {
                    SetDimensions(Int32.Parse(dimensions_new[0]), Int32.Parse(dimensions_new[1]), inkCanvasBackground);
                    SetDimensions(Int32.Parse(dimensions_new[0]), Int32.Parse(dimensions_new[1]), inkCanvasWalk);
                    SetDimensions(Int32.Parse(dimensions_new[0]), Int32.Parse(dimensions_new[1]), inkCanvasPolygons);
                    SetDimensions(Int32.Parse(dimensions_new[0]), Int32.Parse(dimensions_new[1]), inkCanvasFront);
                }
            }
        }

        private void SetDimensions(int width, int height, InkCanvas IC)
        {
            IC.Width = width;
            IC.Height = height;
            IC.UpdateLayout();
        }


        private void PreviewKeyDown(object sender, KeyEventArgs e)
        {
            /*
            if (e.Key == Key.Delete)
            {
                
            }
            */
        }


        private void LayersChanged(object sender, RoutedEventArgs e)
        {
            radioButton_select.IsEnabled = false;
            radioButton_erase.IsEnabled = false;
            radioButton_draw.IsEnabled = false;
            radioButton_polygon.IsEnabled = false;

            groupBoxWalk.Visibility = Visibility.Hidden;

            checkBoxWalk.FontSize = 12;
            checkBoxPolygons.FontSize = 12;
            checkBoxFront.FontSize = 12;

            inkCanvasWalk.Select(new StrokeCollection());
            inkCanvasPolygons.Select(new StrokeCollection());
            inkCanvasFront.Select(new StrokeCollection());

            if ((bool)checkBoxFront.IsChecked)
            {
                checkBoxFront.FontSize = 14;
                inkCanvas1 = inkCanvasFront;

                inkCanvas1.EditingMode = InkCanvasEditingMode.None;
            }
            else if ((bool)checkBoxPolygons.IsChecked)
            {
                checkBoxPolygons.FontSize = 14;
                inkCanvas1 = inkCanvasPolygons;
                radioButton_select.IsEnabled = true;
                radioButton_polygon.IsEnabled = true;

                radioButton_polygon.IsChecked = true;
                inkCanvas1.EditingMode = InkCanvasEditingMode.None;
            }
            else if ((bool)checkBoxWalk.IsChecked)
            {
                checkBoxWalk.FontSize = 14;
                inkCanvas1 = inkCanvasWalk;
                radioButton_select.IsEnabled = true;
                radioButton_erase.IsEnabled = true;
                radioButton_draw.IsEnabled = true;

                radioButton_draw.IsChecked = true;
                inkCanvas1.EditingMode = InkCanvasEditingMode.Ink;
                groupBoxWalk.Visibility = Visibility.Visible;
            }
            else
            {
                inkCanvas1 = inkCanvasBackground;
                inkCanvas1.EditingMode = InkCanvasEditingMode.None;
            }

        }


        private void inkCanvasFront_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (inkCanvasFront.Children.Contains(Charecter))
            {
                inkCanvasFront.Children.Remove(Charecter);
            }
        }

        private void textBoxPolygonName_LostFocus(object sender, RoutedEventArgs e)
        {
            if (IsEditingPolygons())
            {
                if (inkCanvasPolygons.GetSelectedStrokes().Count == 1)
                {
                    ((PolygonStroke)inkCanvasPolygons.GetSelectedStrokes().First()).setName(((TextBox)sender).Text);
                }
            }
        }

        private bool IsEditingPolygons()
        {
            return inkCanvas1.Equals(inkCanvasPolygons);
        }

        private bool IsEditingScreen()
        {
            return inkCanvas1.Equals(inkCanvasFront);
        }
        private bool IsEditingWalk()
        {
            return inkCanvas1.Equals(inkCanvasWalk);
        }

        private void comboBoxPolygonType_LostFocus(object sender, RoutedEventArgs e)
        {
            if (IsEditingPolygons())
            {
                if (inkCanvasPolygons.GetSelectedStrokes().Count == 1)
                {
                    ((PolygonStroke)inkCanvasPolygons.GetSelectedStrokes().First()).SetType((TypeOfPolygon)((ComboBox)sender).SelectedValue);
                }
            }
        }

        private void inkCanvasPolygons_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (textBoxPolygonLookFrom.IsFocused)
            {
                Point position = Mouse.GetPosition(((InkCanvas)sender));
                SetPointOfView(position);
                e.Handled = true;
            }
        }

        private void SetPointOfView(Point position)
        {
            textBoxPolygonLookFrom.Text = "(" + (int)(position.X) + "," + (int)(position.Y) + ")";
            if (IsEditingPolygons())
            {
                if (inkCanvasPolygons.GetSelectedStrokes().Count == 1)
                {
                    char[] delimiters = new char[] { '(', ',', ')' };
                    string[] coordinates = textBoxPolygonLookFrom.Text.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                    if (coordinates.Count() == 2)
                    {
                        ((PolygonStroke)inkCanvasPolygons.GetSelectedStrokes().First()).SetPositionOfwhereToLookFromAtThePolygon(float.Parse(coordinates[0]), float.Parse(coordinates[1]));
                    }
                }
            }
        }

        private void inkCanvasFront_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (textBoxStartPoint.IsFocused)
            {
                Point position = Mouse.GetPosition(((InkCanvas)sender));

                StartPoint.X = position.X;
                StartPoint.Y = position.Y;
                if (IsEditingScreen())
                {
                    RefreshScreenDetails();
                }
                e.Handled = true;
            }
        }

        private void RefreshScreenDetails()
        {
            textBoxStartPoint.Text = "(" + (int)StartPoint.X + "," + (int)StartPoint.Y + ")";
                if (!inkCanvasFront.Children.Contains(Charecter))
                {
                    inkCanvasFront.Children.Add(Charecter);
                }
                InkCanvas.SetTop(Charecter, StartPoint.Y - Charecter.Height );
                InkCanvas.SetLeft(Charecter, StartPoint.X - Charecter.Width / 2);
        }

        private void sliderCharecterSize_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (e.OldValue != 0 && e.NewValue !=0 && this.IsLoaded)
            {
                double diff =  e.NewValue/ e.OldValue;
            Charecter.Height *= diff;
            Charecter.Width *= diff;
            RefreshScreenDetails();
            }
            
        }

        private void sliderColorDepth_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (this.IsLoaded)
            {
                SolidColorBrush solidBrush = ((Slider)sender).Foreground as SolidColorBrush;
                ColorsDepths[solidBrush.Color] = (short)e.NewValue;

                RefreshWalkingDetails();
            }
        }

        private void RefreshWalkingDetails()
        {
            GridBoxWalk.Children.Clear();
            GridBoxWalk.ColumnDefinitions.Clear();
            GridBoxWalk.Background = new SolidColorBrush(Colors.LightGray);
            int i = 0;
            foreach (var item in ColorsDepths)
            {
                Label label = new Label();
                label.Content = item.Value;
                SolidColorBrush SCB = new SolidColorBrush(item.Key);
                label.Foreground = SCB;
                label.FontSize = 30;

                ColumnDefinition CD = new ColumnDefinition();
                GridBoxWalk.ColumnDefinitions.Add(new ColumnDefinition());
                Grid.SetColumn(label, i);
                GridBoxWalk.Children.Add(label);
                i++;

            }
        }

        private void comboBoxPolygonType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count>0 && e.AddedItems[0].Equals(TypeOfPolygon.LookAt))
            {
                textBoxPolygonLookFrom.Visibility = Visibility.Visible;
                labelPolygonLookFrom.Visibility = Visibility.Visible;
            }
            else
            {
                SetPointOfView(new Point(-1,-1));
                textBoxPolygonLookFrom.Visibility = Visibility.Collapsed;
                labelPolygonLookFrom.Visibility = Visibility.Collapsed;

            }
        }

        public static void AddFilesToZip(string ZipPath, string FileToAdd, string InsidePath)
        {
            var zip = ZipFile.Read(ZipPath);
            zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
            zip.AddFile(FileToAdd, InsidePath);
            zip.Save();

        }

        public static void AddDirToZip(string ZipPath, string DirToAdd, string InsidePath)
        {
            var zip = ZipFile.Read(ZipPath);
            zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
            zip.AddDirectory(DirToAdd, InsidePath);
            zip.Save();

        }

        public static void AddStreamToZip(string ZipPath, EntryMemoryStream memo)
        {

            FileInfo ZipFile = new FileInfo(ZipPath);
            ZipFile zipFile = new Ionic.Zip.ZipFile(ZipFile.FullName);
            zipFile.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
            zipFile.AddEntry(memo.GetEntry(), memo);
            zipFile.Save();
        }

        public static void AddStreamsToZip(string ZipPath, List<EntryMemoryStream> memoList)
        {

            FileInfo ZipFile = new FileInfo(ZipPath);
            ZipFile zipFile = new Ionic.Zip.ZipFile(ZipFile.FullName);
            zipFile.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
            foreach (EntryMemoryStream item in memoList)
            {
                zipFile.AddEntry(item.GetEntry(), item);
            }
            zipFile.Save();
        }

        public static MemoryStream ExtractStreamFromZip(string ZipPath, string Entry)
        {

            ZipFile savedFile = new ZipFile(ZipPath);

            MemoryStream memo = new MemoryStream();
            ZipEntry entry = savedFile[Entry];
            if (entry == null)
            {
                return null;
            }
            entry.Extract(memo);  // extract uncompressed content into a memorystream
            memo.Seek(0, SeekOrigin.Begin);
            return memo;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (args.Length > 0)
            {
                if (File.Exists(args[0]))
                {
                    LoadSavedFile(args[0],false);                    
                }
            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            string sMessageBoxText = "?האם ברצונך לשמור עבודתך לפני היציאה";
            string sCaption = "";

            MessageBoxButton btnMessageBox = MessageBoxButton.YesNoCancel;
            MessageBoxImage icnMessageBox = MessageBoxImage.Question;
            MessageBoxResult rsltMessageBox = MessageBox.Show(sMessageBoxText, sCaption, btnMessageBox, icnMessageBox, MessageBoxResult.None, MessageBoxOptions.RightAlign);
            if (rsltMessageBox == MessageBoxResult.Yes)
            {
                AllDone();
            }
            else if (rsltMessageBox == MessageBoxResult.Cancel)
            {
                e.Cancel = true;
            }
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            AllDone();
        }

        
    }
}
